''' <summary>
''' This class serves as the base for all the tabs (including the dropdown).  It provides common
''' rendering logic and highlighting behavior.
''' </summary>
Friend Class TabBaseControl
    Inherits Control

    Protected ReadOnly Property TopMargin() As Integer
        Get
            If (Me.Pages IsNot Nothing) Then Return Me.Pages.TopMargin
            Return 0
        End Get
    End Property

    Protected ReadOnly Property Pages() As PageCollection
        Get
            If (Me.Parent Is Nothing) Then Return Nothing
            Return DirectCast(Me.Parent, TabView).Pages
        End Get
    End Property

    Public Shared Function AddColor(ByVal color As Drawing.Color, ByVal value As Integer) As Color
        If (value > 0) Then
            Return Drawing.Color.FromArgb(Math.Min(color.R + value, 255), Math.Min(color.G + value, 255), Math.Min(color.B + value, 255))
        Else
            Return Drawing.Color.FromArgb(Math.Max(color.R + value, 0), Math.Max(color.G + value, 0), Math.Max(color.B + value, 0))
        End If
    End Function

    Public Shared Function GetBorderPen(ByVal tabColor As Color) As Pen
        Return New Pen(AddColor(tabColor, -50))
    End Function

    Protected Overridable ReadOnly Property IsHighlighted() As Boolean
        Get
            Return Me.ClientRectangle.Contains(Me.PointToClient(Control.MousePosition))
        End Get
    End Property

    Private Sub TabPageControl_MouseEnter(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.MouseEnter
        Me.Invalidate()
    End Sub

    Private Sub TabPageControl_MouseLeave(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.MouseLeave
        Me.Invalidate()
    End Sub

    Protected Sub PaintBackground(ByVal e As System.Windows.Forms.PaintEventArgs, ByVal bounds As Rectangle, ByVal gradientBounds As RectangleF, ByVal color1 As Color, ByVal color2 As Color, Optional ByVal paintRightLine As Boolean = False)
        ' OK. Ready to paint the background gradient and whatnot.
        Using bgBrush As New Drawing2D.LinearGradientBrush(gradientBounds, color1, color2, Drawing2D.LinearGradientMode.Vertical)
            Dim path As New Drawing2D.GraphicsPath()
            Dim arcSize As Single = 5

            Dim smoothMode As Drawing2D.SmoothingMode = e.Graphics.SmoothingMode
            e.Graphics.SmoothingMode = Drawing2D.SmoothingMode.AntiAlias

            path.AddLine(bounds.Right, bounds.Bottom, bounds.Left, bounds.Bottom)
            path.AddLine(bounds.Left, bounds.Bottom, bounds.Left, bounds.Top + arcSize)
            path.AddArc(bounds.Left, bounds.Top, arcSize, arcSize, 180, 90)
            path.AddLine(bounds.Left + arcSize, bounds.Top, bounds.Width - arcSize, bounds.Top)
            path.AddArc(bounds.Width - arcSize, bounds.Top, arcSize, arcSize, 270, 90)

            bgBrush.WrapMode = Drawing2D.WrapMode.TileFlipXY
            e.Graphics.FillPath(bgBrush, path)

            Using borderPen As Pen = GetBorderPen(Pages.TabColor)
                path = New Drawing2D.GraphicsPath()
                path.AddLine(bounds.Right - 1, bounds.Bottom, bounds.Left, bounds.Bottom)
                path.AddLine(bounds.Left, bounds.Bottom, bounds.Left, bounds.Top + arcSize)
                path.AddArc(bounds.Left, bounds.Top, arcSize, arcSize, 180, 90)
                path.AddLine(bounds.Left + arcSize - 1, bounds.Top, bounds.Width - 1 - arcSize, bounds.Top)
                path.AddArc(bounds.Width - arcSize - 1, bounds.Top, arcSize, arcSize, 270, 90)
                If (paintRightLine OrElse Me.Parent.Controls(Me.Parent.Controls.Count - 1) Is Me) Then path.CloseFigure()
                e.Graphics.DrawPath(borderPen, path)
            End Using

            e.Graphics.SmoothingMode = smoothMode
        End Using
    End Sub

    Protected Overrides Sub OnPaint(ByVal e As System.Windows.Forms.PaintEventArgs)
        If (Me.Pages Is Nothing) Then Exit Sub

        ' Set up the gradient parameters.
        Dim bounds As Rectangle = Nothing

        ' Modify the gradient based on the state of the control (IsSelected, IsHighlighted, Default)
        bounds = New Rectangle(0, TopMargin, Me.Width, Me.Height - TopMargin - 1)
        If (Me.IsHighlighted) Then
            PaintBackground(e, bounds, New RectangleF(0, 0, bounds.Width, bounds.Height / 2), AddColor(Pages.TabColor, 50), Pages.TabColor)
        Else
            PaintBackground(e, bounds, bounds, AddColor(Pages.TabColor, 25), AddColor(Pages.TabColor, -25))
        End If
    End Sub
End Class
